package com.jadcon.bedbreakfast.domain;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

@Service("reservationService")
public class ReservationServiceImpl implements ReservationService {
	
	@Autowired
	private ReservationRepository reservationRepository;
	@Autowired
	private SuiteService suiteService;

	public List<Suite> equalsDateRange(Date checkIn, Date checkOut) {

		List<Suite> suiteList = suiteService.getSuiteList();
		List<Suite> suitesNotAvailable = new ArrayList<Suite>();
		List<Reservation> reservationList = reservationRepository
				.getReservationList();

		for (Reservation reservation : reservationList) {
			if (reservation.getCheckIn().equals(checkIn)
					|| reservation.getCheckIn().equals(checkOut)
					|| (reservation.getCheckIn().after(checkIn) && reservation
							.getCheckIn().before(checkOut))
					|| reservation.getCheckOut().equals(checkIn)
					|| reservation.getCheckOut().equals(checkOut)
					|| (reservation.getCheckOut().after(checkIn) && reservation
							.getCheckOut().before(checkOut))) {

				// if there is a match, get the suite number off the
				// reservation, and make a list of unavailable suites
				int number = reservation.getRoomNumber();
				for (Suite suite : suiteList) {
					if (suite.getNumber() == number) {

						if (suitesNotAvailable.contains(suite)) {
							continue;
						} else
							suitesNotAvailable.add(suite);
					}
				}
			}
		}

		suiteList.removeAll(suitesNotAvailable);
		return suiteList;

	}

	public boolean SuiteAvailableForReservation(Reservation newReservation) {
		int roomNumber = newReservation.getRoomNumber();
		Date checkIn = newReservation.getCheckIn();
		Date checkOut = newReservation.getCheckOut();

		List<Reservation> reservationList = findReservationByRoom(roomNumber);
		for (Reservation reservation : reservationList) {
			if (reservation.getCheckIn().equals(checkIn)
					|| reservation.getCheckIn().equals(checkOut)
					|| (reservation.getCheckIn().after(checkIn) && reservation
							.getCheckIn().before(checkOut))
					|| reservation.getCheckOut().equals(checkIn)
					|| reservation.getCheckOut().equals(checkOut)
					|| (reservation.getCheckOut().after(checkIn) && reservation
							.getCheckOut().before(checkOut))) {
				return false;
			}
		}
		return true;
	}

	public List<Reservation> getReservationList() {
		// get the current logged in user
		boolean canViewAllReservations = false;
		User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		for (GrantedAuthority authority : user.getAuthorities())
		if(("ROLE_VIEW_ALL_RESERVATION").equals(authority.getAuthority())){
			canViewAllReservations = true;
			break;
		}
		
		if (canViewAllReservations) {
			return reservationRepository.getReservationList();
		} else {
			String username = SecurityContextHolder.getContext().getAuthentication().getName();
			return reservationRepository.getReservationList(username);
		}	

	}

	public List<Reservation> findByNumber(int reservationNumber) {
		// get the current logged in user
		boolean canViewAllReservations = false;
		User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		for (GrantedAuthority authority : user.getAuthorities())
		if(("ROLE_VIEW_ALL_RESERVATION").equals(authority.getAuthority())){
			canViewAllReservations = true;
			break;
		}
        
		if (canViewAllReservations) {
			return reservationRepository.findByNumber(reservationNumber);
		} else {
			String username = SecurityContextHolder.getContext().getAuthentication().getName();
			return reservationRepository.findByNumber(reservationNumber, username);
		}	
	}

	public void save(Reservation reservation) {
		String username = SecurityContextHolder.getContext().getAuthentication().getName();
		reservation.setUsername(username);
		reservationRepository.save(reservation);
	}

	public List<Reservation> findReservationByRoom(int roomNumber) {
		// get the current logged in user
		boolean canViewAllReservations = false;
		User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		for (GrantedAuthority authority : user.getAuthorities())
		if(("ROLE_VIEW_ALL_RESERVATION").equals(authority.getAuthority())){
			canViewAllReservations = true;
			break;
		}
		
		if (canViewAllReservations) {
			return reservationRepository.findReservationByRoom(roomNumber);
		} else {
			String username = SecurityContextHolder.getContext().getAuthentication().getName();
			return reservationRepository.findReservationByRoom(roomNumber, username);
		}
	}

	public List<Reservation> findReservationByStartDate(Date checkIn) {
		
		// get the current logged in user
		boolean canViewAllReservations = false;
		User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		for (GrantedAuthority authority : user.getAuthorities())
		if(("ROLE_VIEW_ALL_RESERVATION").equals(authority.getAuthority())){
			canViewAllReservations = true;
			break;
		}
       
		if (canViewAllReservations) {
			return reservationRepository.findReservationByStartDate(checkIn);
		} else {
			String username = SecurityContextHolder.getContext().getAuthentication().getName();
			return reservationRepository.findReservationByStartDate(checkIn, username);
		}
	}

	public void delete(int reservationNumber) {
		reservationRepository.delete(reservationNumber);
	}

	public Reservation getReservationNumberForNewlyCreatedReservation(
			Reservation reservation) {
		return reservationRepository.getReservationNumberForNewlyCreatedReservation(reservation);
	}

	public List<Reservation> findByUsername(String username) {
		return reservationRepository.findByUsername(username);
	}
	
	

}
